<template>
  <div class="page-common-layout custom-tablePage-container">
    <div class="table-body-container">
      <div class="process-operate">
        <div class="date">
          <div class="item">开始时间：{{ form.startTime || "-" }}</div>
          <div class="item">结束时间：{{ form.endTime || "-" }}</div>
          <div class="item">
            状态：
            <span class="state">
              <icon-fonts
                icon="icon-daojishi"
                type="small"
                style="margin-right:5px;"
              >
              </icon-fonts>
              {{ filterStatus(form.status) || "-" }}
            </span>
          </div>
        </div>

        <a-button type="primary" @click="handleUpload()">
          线下流程
        </a-button>
        <a-button @click="handleExport()" v-action:bpbj_download>
          导出
        </a-button>
        <a-button icon="search" v-action:bpbj_zsglxt>
          知识管理系统文件检索
        </a-button>
      </div>

      <!-- 线下流程 -->
      <div class="img-container" v-if="form.isOfflineProcess == 1">
        <iframe
          :src="fileUrl"
          frameborder="0"
          id="preFileIframe"
          width="100%"
          height="100%"
        ></iframe>
      </div>
      <!-- 流程图 -->
      <div class="graph-container" v-if="form.isOfflineProcess == 0">
        <div class="graph-dom" id="graph-dom"></div>
        <div class="legend">
          <div class="legend-item">未开始</div>
          <div class="legend-item">进行中</div>
          <div class="legend-item">已完成</div>
          <div class="legend-item">延期</div>
        </div>
      </div>
    </div>
    <!--  -->
    <div class="page-footer-warp">
      <div class="label">报批报建常用网站：</div>
      <div class="list-warp">
        <div
          class="website-item"
          v-for="(item, index) in websiteSource"
          :key="index"
          @click="hrefWebsite(item)"
        >
          {{ item.title }}
        </div>
      </div>
    </div>

    <!-- 上传图片 -->
    <uploadImgModal
      :visible.sync="uploadImgModal.visible"
      :row="form"
    ></uploadImgModal>
  </div>
</template>

<script>
//
import { axios } from "@/utils/request";
import { downloadDfs, getToken } from "@/utils/TopVUI";
import { Graph, Shape, DataUri } from "@antv/x6";
import { mapGetters } from "vuex";
import "@antv/x6-vue-shape";
import { detailFlowPath, getListByProcessId } from "@/api/knowledgeBase";
//上传图片
import uploadImgModal from "./components/uploadImgModal.vue";
//节点
import CustomNode from "./components/nodeItme.vue";
export default {
  components: {
    uploadImgModal,
    CustomNode,
  },
  provide() {
    return {};
  },
  data() {
    return {
      //常用网站
      websiteSource: [],
      //详情
      form: {},
      //上传图片
      uploadImgModal: {
        visible: false,
      },
      fileUrl: "",
      //流程图
      cells: [],
      graph: null,
      status: [],
    };
  },
  computed: {
    ...mapGetters(["configData"]),
    kkFileView() {
      let index = this.configData.findIndex(
        (item) => item.code === "kkFileView"
      );
      if (index >= 0) {
        return this.configData[index].value;
      } else {
        return "http://192.168.1.216:8012/onlinePreview";
      }
    },
  },
  mounted() {
    this.getData();
    this.getWebsiteData();
  },
  methods: {
    analysisPath(file) {
      let dealData = JSON.parse(file ?? "{}");
      let { url } = dealData;
      this.fileUrl =
        this.kkFileView +
        "/onlinePreview?url=" +
        encodeURIComponent(Base64.encode(url)) +
        "&watermarkTxt=" +
        //水印内容
        encodeURIComponent("") +
        "&token=" +
        getToken();
    },
    handleUpload() {
      this.uploadImgModal.visible = true;
    },
    handleExport() {
      let { isOfflineProcess, offlineProcessFile, proName } = this.form;
      //线下流程
      if (isOfflineProcess == 1) {
        downloadDfs(offlineProcessFile);
      }
      //流程图
      if (isOfflineProcess == 0) {
        this.graph.toPNG(
          (dataUri) => {
            //下载
            DataUri.downloadDataUri(dataUri, `${proName}.png`);
          },
          {
            quality: 1,
            stylesheet: `.custom-node-container {
  width: 210px;
  height: 138px;
  background: #ffffff;
  box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.1);
  border-radius: 4px 4px 4px 4px;
  border: 1px solid #dcdee2;
  display: flex;
  flex-direction: column;
  .state-container {
    height: 40px;
    background: #fafafa;
    border-radius: 4px 4px 0px 0px;
    border-bottom: 1px solid #dcdee2;
    display: flex;
    align-items: center;
    padding: 0 10px;
    box-sizing: border-box;
    font-size: 14px;
    color: #666666;
    .icon {
      width: 20px;
      height: 20px;
      margin-right: 10px;
      &.bg_1 {
        background: url("~@/assets/img/icon_19.png");
        background-size: 100% 100%;
      }
      &.bg_2 {
        background: url("~@/assets/img/icon_9.png");
        background-size: 100% 100%;
      }
      &.bg_3 {
        background: url("~@/assets/img/icon_12.png");
        background-size: 100% 100%;
      }
      &.bg_4 {
        background: url("~@/assets/img/icon_11.png");
        background-size: 100% 100%;
      }
    }
  }
  .content {
    flex: 1;
    padding: 10px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    .name {
      font-weight: 400;
      font-size: 16px;
      color: #333333;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      overflow: hidden;
      text-overflow: ellipsis;
      -webkit-line-clamp: 1;
    }
    .time {
      font-size: 12px;
      color: #8a9295;
    }
  }
}`,
          }
        );
      }
    },

    filterStatus(val) {
      switch (Number(val)) {
        case 0:
          return "未开始";
        case 1:
          return "进行中";
        case 2:
          return "已完成";
        default:
          break;
      }
    },

    getData() {
      Promise.all([this.getDetail(), this.getStateData()])
        .then(() => {
          if (this.form.isOfflineProcess == 0) {
            this.$nextTick(() => {
              // 初始化画布
              this.initGraph();
              // 初始化连接桩
              this.initPorts();
              // 渲染所有左侧控件图形
              this.loadStencil();
              this.cells.forEach((v) => {
                v.tools = [];
                if (
                  v.shape == "custom-rect" &&
                  !v?.data?.parent &&
                  v.attrs.text
                ) {
                  v.attrs.text.text = "";
                  v.shape = "custom-node";
                }
              });
              //追加额外参数
              this.cells.forEach((item) => {
                this.status.forEach((v) => {
                  if (item.id == v.nodeId) {
                    item.data = { ...item.data, ...v };
                  }
                });
              });
              // 清空画布
              this.graph.clearCells();
              // 渲染节点数据
              this.graph.fromJSON({
                cells: this.cells,
              });
            });
          }
        })
        .catch();
    },
    //查询详情
    getDetail() {
      return new Promise((resolve, reject) => {
        detailFlowPath({})
          .then((res) => {
            let { data } = res;
            let { isOfflineProcess, offlineProcessFile } = data;
            let source = JSON.parse(data?.processContent ?? "[]") ?? [];
            this.cells = source;
            //线下流程
            if (isOfflineProcess == 1) {
              this.analysisPath(offlineProcessFile);
            }
            resolve();
          })
          .catch((_) => {
            reject();
          })
          .finally((_) => {});
      });
    },

    //查询节点状态
    getStateData() {
      return new Promise((resolve, reject) => {
        getListByProcessId({})
          .then((res) => {
            let { data } = res;
            this.form = data;
            this.status = data?.nodeList;
            resolve();
          })
          .catch((_) => {
            this.form = {};
            this.status = [];
            reject();
          });
      });
    },

    // 初始化画布
    initGraph() {
      // 初始化画布
      this.graph = new Graph({
        container: document.getElementById("graph-dom"),
        //禁止节点平移
        interacting: function(cellView) {
          return { nodeMovable: false };
        },
        grid: {
          // 绘制网格
          visible: true,
          // 指定网格类型
          type: "mesh",
          args: {
            color: "#ddd", // 网格线/点颜色
            thickness: 1, // 网格线宽度/网点大小
          },
        },
        async: true,
        //允许画布拖拽
        panning: {
          enabled: true,
          eventTypes: ["leftMouseDown", "mouseWheel"],
        },
        mousewheel: {
          enabled: true,
          zoomAtMousePosition: true,
          modifiers: "ctrl",
          minScale: 0.5,
          maxScale: 3,
        },
        connecting: {
          router: {
            name: "manhattan",
            args: {
              padding: 1,
            },
          },
          connector: {
            name: "rounded",
            args: {
              radius: 8,
            },
          },
          anchor: "center",
          connectionPoint: "anchor",
          allowBlank: false,
          snap: {
            radius: 20,
          },
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  stroke: "#A2B1C3",
                  strokeWidth: 2,
                  targetMarker: {
                    name: "block",
                    width: 12,
                    height: 8,
                  },
                },
              },
              zIndex: 0,
            });
          },
          validateConnection({ targetMagnet }) {
            return !!targetMagnet;
          },
        },
        highlighting: {
          magnetAdsorbed: {
            name: "stroke",
            args: {
              attrs: {
                fill: "#5F95FF",
                stroke: "#5F95FF",
              },
            },
          },
        },
      });
    },

    // 初始化链接桩
    initPorts() {
      this.ports = {
        groups: {
          top: {
            position: "top",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          right: {
            position: "right",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          bottom: {
            position: "bottom",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          left: {
            position: "left",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
        },
        items: [
          {
            group: "top",
          },
          {
            group: "right",
          },
          {
            group: "bottom",
          },
          {
            group: "left",
          },
        ],
      };
    },

    // 渲染所有左侧控件图形
    loadStencil() {
      // 注册节点
      Graph.registerNode(
        "custom-node",
        {
          inherit: "vue-shape",
          width: 210,
          height: 138,
          component: {
            render: (h) =>
              h(CustomNode, {
                on: {
                  // 监听 CustomNode组件触发的事件，获取传递出来的数据
                  nodeEvent: (data) => {
                    // console.log("组件点击事件：", data);
                    if (data.menuPath) {
                      this.$router.push({
                        path: data.menuPath,
                      });
                    }
                  },
                },
              }),
          },
          ports: { ...this.ports },
        },
        true
      );
      Graph.registerNode(
        "custom-rect",
        {
          inherit: "rect",
          width: 100,
          height: 40,
          attrs: {
            body: {
              strokeWidth: 1,
              stroke: "#666666",
              fill: "#fff",
            },
            text: {
              fontSize: 12,
              fill: "#8c8c8c",
            },
          },
          ports: { ...this.ports },
        },
        true
      );
    },

    //查询常用网站列表
    getWebsiteData() {
      return new Promise((resolve, reject) => {
        axios
          .post(
            `/probusiness/expansionSystem/getList`,
            {},
            {
              headers: {
                "Content-Type": "application/json",
              },
            }
          )
          .then((res) => {
            let { data } = res;
            this.websiteSource = data || [];
          })
          .catch((_) => {
            this.websiteSource = [];
            resolve();
          })
          .finally((_) => {});
      });
    },

    //跳转常用网站
    hrefWebsite(data = {}) {
      let { url } = data;
      url && window.open(url);
    },
  },
  destroyed() {
    this.graph && this.graph.dispose();
  },
};
</script>

<style lang="scss" scoped>
.custom-tablePage-container {
  .table-body-container {
    overflow: hidden;
    .process-operate {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      /deep/.ant-btn {
        margin-right: 10px;
      }
    }
    .title {
      text-align: center;
      font-weight: 400;
      font-size: 32px;
      color: #333333;
      margin: 10px 0;
    }
    .date {
      flex: 1;
      display: flex;
      justify-content: center;
      margin: 10px 0 10px 0;
      .item {
        margin-right: 50px;
        font-weight: 400;
        font-size: 16px;
        color: #333333;
        .state {
          color: #ff6f42;
        }
      }
    }
    .graph-container {
      flex: 1;
      overflow: hidden;
      position: relative;
      .graph-dom {
        height: 100%;
        width: 100%;
      }
      .legend {
        position: absolute;
        left: 50%;
        transform: translate(-50%);
        bottom: 20px;
        display: flex;
        align-items: center;
        .legend-item {
          font-weight: 400;
          font-size: 14px;
          color: #666666;
          margin-right: 48px;
          &::before {
            display: inline-block;
            content: "";
            position: relative;
            top: 4px;
            margin-right: 10px;
            width: 20px;
            height: 20px;
          }
        }
        .legend-item:nth-child(1) {
          &::before {
            background: url("~@/assets/img/icon_19.png");
            background-size: 100% 100%;
          }
        }
        .legend-item:nth-child(2) {
          &::before {
            background: url("~@/assets/img/icon_9.png");
            background-size: 100% 100%;
          }
        }
        .legend-item:nth-child(3) {
          &::before {
            background: url("~@/assets/img/icon_12.png");
            background-size: 100% 100%;
          }
        }
        .legend-item:nth-child(4) {
          &::before {
            background: url("~@/assets/img/icon_11.png");
            background-size: 100% 100%;
          }
        }
      }
    }
    .img-container {
      flex: 1;
      overflow: hidden;
      img {
        height: 100%;
        width: 100%;
        object-fit: contain;
      }
    }
  }
  .page-footer-warp {
    background: #fff;
    margin-top: 10px;
    border-radius: 6px;
    padding: 25px 16px;
    display: flex;
    color: #333;
    font-size: 14px;
    .label {
      flex-shrink: 0;
      margin-right: 12px;
    }
    .list-warp {
      flex: 1;
      flex-wrap: wrap;
      display: flex;
      color: #666;
      .website-item {
        display: flex;
        align-items: center;
        cursor: pointer;
        &:hover {
          text-decoration: underline;
        }
        &:not(:last-child) {
          margin-right: 50px;
        }
        &::before {
          content: "";
          display: flex;
          width: 6px;
          height: 6px;
          border-radius: 50%;
          background: #f07f17;
          margin-right: 10px;
        }
      }
    }
  }
}
</style>
